﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AvantGameMachine.Graphics
{
    public class TextRenderObject : IRenderizableObject
    {
        private string text = string.Empty;
        private Font myFont = null;
        private List<RenderChar> chars = new List<RenderChar>();
        private TextAlignement tAlignement = TextAlignement.AlignementCenter;
        private float alignedPosX = 0.0f;
        private float alignedPosY = 0.0f;
        private TextView tView = TextView.ViewMiddle;

        public TextRenderObject()
        {
            NeedsBlend = true;
            sChanged += this.ScaleChanged;
        }

        public void ScaleChanged()
        {
            RealignText();
        }

        public Font TextFont
        {
            get { return myFont;  }
            set { myFont = value; }
        }

        public string Text
        {
            get { return text; }
            set
            {
                if (text != value)
                {
                    text = value;
                    UpdateText();
                }
            }
        }

        public float AlignedPosX
        {
            get { return alignedPosX; }
            set
            {
                if (alignedPosX != value)
                {
                    alignedPosX = value;
                    RealignText();
                }
            }
        }

        public TextAlignement Alignement
        {
            get { return tAlignement; }
            set
            {
                if (tAlignement != value)
                {
                    tAlignement = value;
                    RealignText();
                }
            }
        }

        public TextView View
        {
            get { return tView; }
            set
            {
                if (tView != value)
                {
                    tView = value;
                    UpdateText();
                }
            }
        }

        private void RealignText()
        {
            Size2D length;

            switch (tAlignement)
            {
                case TextAlignement.AlignementCenter:
                    position.X = alignedPosX;
                    break;
                case TextAlignement.AlignementLeft:
                    length = GetTextLength(text);
                    position.X = alignedPosX + ((length.Widthf / 2.0f) * scale.X);
                    break;
                case TextAlignement.AlignementRight:
                    length = GetTextLength(text);
                    position.X = alignedPosX - ((length.Widthf / 2.0f) * scale.X);
                    break;
            }
        }

        private void ReviewText()
        {

            switch (tView)
            {
                case TextView.ViewMiddle:
                    alignedPosY = 0.0f;
                    break;
                case TextView.ViewDown:
                    alignedPosY = myFont.FontSize.Heightf;
                    break;
                case TextView.ViewTop:
                    alignedPosY = -1.0f * myFont.FontSize.Heightf;
                    break;
            }
        }

        internal Size2D GetTextLength(string _text)
        {
            Size2D sz = new Size2D(0.0f,0.0f);
            foreach (char ch in _text)
            {
                Size2D tmp = (myFont.GetChar(ch).Advance);
                sz.Widthf += tmp.Widthf;
                FontChar fc = myFont.GetChar(ch);
                sz.Heightf = ((fc.BLen.Heightf / 2) + (fc.BTopLeft.Heightf) / 2);
                if (tmp.Heightf > sz.Heightf)
                    sz.Heightf = tmp.Heightf;
            }

            return sz;
        }

        private void UpdateText()
        {
            chars.Clear();
            this.DisposeChildren();

            Size2D sz = GetTextLength(text);
            PosVector v = new PosVector(-1 * ((sz.Widthf) / 2.0f), (sz.Heightf) / 2.0f, 0.0f);

            ReviewText();

            float fcAdvWidtf2;
            FontChar fc;
            RenderChar nc;

            foreach (char ch in text)
            {
                nc = this.CreateNew<RenderChar>("Character" + ch);
                chars.Add(nc);
                fc = myFont.GetChar(ch);
                fcAdvWidtf2 = (fc.Advance.Widthf / 2);
                nc.SetChar(fc);
                v.X += fcAdvWidtf2;
                v.Y = alignedPosY + ((fc.BLen.Heightf / 2) + (fc.BTopLeft.Heightf)) - (sz.Heightf / 2);
                nc.Position = new PosVector(v.X, v.Y, 0.0f);
                v.X += fcAdvWidtf2;
            }
            RealignText();
        }
    }
}
